package com.uziot.bucket.dubbo.provider;

import com.uziot.bucket.dubbo.service.AsyncTestService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.rpc.RpcContext;

import java.util.concurrent.CompletableFuture;

/**
 * @author shidt
 * @version V1.0
 * @className AsyncTestServiceImpl
 * @date 2020-11-28 15:46:46
 * @description 模拟异步服务接口
 * 注意：Provider端异步执行和Consumer端异步调用是相互独立的，你可以任意正交组合两端配置
 */
@Slf4j
@DubboService(
        group = "dev",
        version = "1.0.0",
        cluster = "failover",
        retries = 3,
        loadbalance = "leastactive",
        interfaceClass = AsyncTestService.class)
public class AsyncTestServiceImpl implements AsyncTestService {

    @Override
    public CompletableFuture<String> sayHello(String name) {
        return syncExec(name);
//        return asyncExec(name);
    }

    private CompletableFuture<String> syncExec(String name) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String result = "同步提供程序的响应（completedFuture方法）： " + name;
        log.info(result);
        return CompletableFuture.completedFuture(result);
    }

    private CompletableFuture<String> asyncExec(String name) {
        RpcContext savedContext = RpcContext.getContext();
        // 建议为supplyAsync提供自定义线程池，避免使用JDK公用线程池
        return CompletableFuture.supplyAsync(() -> {
            System.out.println(savedContext.getAttachment("consumer-key1"));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String result = "提供者的异步响应（RpcContext方式）： " + name;
            log.info(result);
            return result;
        });
    }

}
